package com.kakavr.wxpay.service;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;

import com.beust.jcommander.internal.Lists;
import com.google.common.collect.Maps;
import com.kakavr.base.service.BaseService;
import com.kakavr.pay.constant.PayConstant;
import com.kakavr.pay.constant.WxConstant;
import com.kakavr.pay.util.HttpClientUtil;
import com.kakavr.pay.util.WXPayUtil;
import com.kakavr.user.service.IUserRechargeService;
import com.kakavr.util.ConvertUtils;
import com.kakavr.wxpay.dao.IWXPayDao;

@Service
public class WXPayService extends BaseService implements IWXPayService {
	@Resource
	private IWXPayDao wXPayDao;
	@Resource
	private IUserRechargeService userRechargeService;

	@Override
	public boolean updateWXpayLogByNotify(String xml) {
		try {
			debug("微信后端通知信息："+xml);
			Map<String, String> data = WXPayUtil.xmlToMap(xml);
			if (WXPayUtil.isSignatureValid(data, WxConstant.getAppKey())) {
				String outTradeNo = data.get("out_trade_no");
				if (PayConstant.isHaveCode(outTradeNo)) {
					info("微信支付后端响应重复");
					return true;
				}
				if ("SUCCESS".equals(data.get("result_code"))) {
					Map<String, Object> logMap = wXPayDao
							.selectWXpayByOutTradeNo(data);
					if (null == logMap || logMap.isEmpty()) {
						error("微信支付后端未取到支付的具体信息，参数为：" + xml);
						return false;
					}
					int status = (int) logMap.get("status");
					if (status < 99) {
						info("微信支付已通知，微信支付状态status=" + status);
						return true;
					}
					Object couponFee = data.get("coupon_fee");
					if(null != couponFee){
						couponFee = NumberUtils.toInt(couponFee.toString())/100;
					}
					//实际支付金额
					Object setTotalFee = data.get("settlement_total_fee");
					if(null != setTotalFee){
						setTotalFee = NumberUtils.toInt(setTotalFee.toString())/100;
					}else{
						setTotalFee = logMap.get("totalfee");
					}
					userRechargeService.updateUserRechargeByPay(
							logMap.get("userId"), outTradeNo,
							setTotalFee,couponFee);
					data.put("status", "1");
				} else {
					data.put("status", "2");
				}
				data.put("notifyinfo", xml);
				wXPayDao.updateWXpayLog(data);
				return true;
			}
		} catch (Exception e) {
		}
		return false;
	}

	@Override
	public String addWXpayLog(Map<String, Object> map) {
		Map<String, String> result = null;
		try {
			result = this.unifiedOrder(map);
			wXPayDao.insertWXpayLog(map);
		} catch (Exception e) {
			error("微信支付预支付出错，错误信息：" + e);
			return null;
		}
		if (null == result) {
			return null;
		}
		return result.get("code_url");
	}

	/**
	 * 微信 统一下单
	 * 
	 * @param map
	 * @return
	 * @throws Exception
	 */
	private Map<String, String> unifiedOrder(Map<String, Object> map)
			throws Exception {
		Map<String, String> orderMap = Maps.newHashMap();
		orderMap.put("appid", WxConstant.getAppId());
		orderMap.put("mch_id", WxConstant.getMchId());
		orderMap.put("nonce_str", WXPayUtil.generateUUID());
		orderMap.put("body", WxConstant.BODY);
		orderMap.put("version", "1.0");
		orderMap.put("out_trade_no", (String) map.get("tradeno"));
		Double amoutDouble = NumberUtils.toDouble(map.get("amount").toString()) * 100;
		orderMap.put("total_fee", amoutDouble.intValue()+"");
		orderMap.put("spbill_create_ip", (String) map.get("spbillIp"));
		orderMap.put("notify_url", WxConstant.getNotifyUrl());
		orderMap.put("trade_type", WxConstant.TRADE_TYPE);
		Map<String,Object> detail = Maps.newHashMap();
		List<Map<String,Object>> list = Lists.newArrayList();
		Map<String,Object> goods = Maps.newHashMap();
		goods.put("goods_id", map.get("ruleId"));
		goods.put("wxpay_goods_id", map.get("ruleId"));
		goods.put("quantity", 1);
		goods.put("price", amoutDouble.intValue());
		list.add(goods);
		detail.put("goods_detail", list);
		detail.put("cost_price", amoutDouble.intValue());
		orderMap.put("detail", ConvertUtils.POToJson(detail));
		orderMap.put("goods_tag", (String)map.get("ruleId"));
		String xml = WXPayUtil.generateSignedXml(orderMap,
				WxConstant.getAppKey());
		Map<String, String> result = HttpClientUtil.doPostByXML(
				WxConstant.getUfdoderUrl(), xml);
		map.putAll(orderMap);
		map.putAll(result);
		return result;
	}

}
